#include "ui/CustomScrollView.h"
#include <QScrollBar>
#include <QResizeEvent>
#include <QPropertyAnimation>
#include <QPainter>
#include <QTimer>

class CustomScrollViewThumb : public QWidget {
    Q_OBJECT
public:
    explicit CustomScrollViewThumb(Qt::Orientation o, QWidget *parent = nullptr)
        : QWidget(parent), orient(o)
    {
        setAttribute(Qt::WA_TransparentForMouseEvents);
        setAttribute(Qt::WA_NoSystemBackground);
        setAttribute(Qt::WA_StyledBackground, false);
    }

    void setColor(const QColor &c) { color = c; update(); }

protected:
    void paintEvent(QPaintEvent *) override {
        QPainter p(this);
        p.setRenderHint(QPainter::Antialiasing, true);
        p.setPen(Qt::NoPen);
        p.setBrush(color);
        QRect r = rect().adjusted(1, 1, -1, -1);
        p.drawRoundedRect(r, 4, 4);
    }

private:
    Qt::Orientation orient;
    QColor color = QColor(160, 174, 192, 180);
};

CustomScrollView::CustomScrollView(QWidget *parent)
    : QScrollArea(parent)
{
    setWidgetResizable(true);
    setFrameShape(QFrame::NoFrame);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    initThumbs();

    // 监听内置滚动条，以便同步自定义滑块位置
    connect(verticalScrollBar(), &QScrollBar::valueChanged,
            this, &CustomScrollView::onVScrollChanged);
    connect(horizontalScrollBar(), &QScrollBar::valueChanged,
            this, &CustomScrollView::onHScrollChanged);
}

void CustomScrollView::setContentWidget(QWidget *w)
{
    setWidget(w);
    if (widget()) widget()->installEventFilter(this);
    updateThumbsGeometry();
}

void CustomScrollView::resizeEvent(QResizeEvent *e)
{
    QScrollArea::resizeEvent(e);
    updateThumbsGeometry();
}

bool CustomScrollView::eventFilter(QObject *watched, QEvent *event)
{
    if (watched == widget()) {
        if (event->type() == QEvent::Resize) {
            QTimer::singleShot(0, this, &CustomScrollView::updateThumbsGeometry);
        }
    }
    return QScrollArea::eventFilter(watched, event);
}

void CustomScrollView::onVScrollChanged(int)
{
    updateThumbsGeometry();
}

void CustomScrollView::onHScrollChanged(int)
{
    updateThumbsGeometry();
}

void CustomScrollView::initThumbs()
{
    if (!m_vThumb) {
        m_vThumb = new CustomScrollViewThumb(Qt::Vertical, this);
        m_vThumb->setFixedWidth(6);
        m_vThumb->setColor(QColor(160,174,192,180));
        m_vThumb->hide();
    }
    if (!m_hThumb) {
        m_hThumb = new CustomScrollViewThumb(Qt::Horizontal, this);
        m_hThumb->setFixedHeight(6);
        m_hThumb->setColor(QColor(160,174,192,150));
        m_hThumb->hide();
    }
}

int CustomScrollView::verticalTrackLength() const
{
    // 轨道为 viewport 高度
    return viewport()->height();
}

int CustomScrollView::horizontalTrackLength() const
{
    // 轨道为 viewport 宽度
    return viewport()->width();
}

void CustomScrollView::updateThumbsGeometry()
{
    if (!widget()) return;

    const int vRange = verticalScrollBar()->maximum() - verticalScrollBar()->minimum();
    const int hRange = horizontalScrollBar()->maximum() - horizontalScrollBar()->minimum();

    // 固定滑块长度
    const int vThumbLen = 24;
    const int hThumbLen = 24;

    // 为自定义滑块预留右/下边距，避免与内容重叠
    const int rightBand = (vRange > 0) ? (m_vThumb->width() + 4) : 0;
    const int bottomBand = (hRange > 0) ? (m_hThumb->height() + 4) : 0;
    setViewportMargins(0, 0, rightBand, bottomBand);

    // 纵向滑块
    if (vRange > 0) {
        const int track = verticalTrackLength();
        const double posRatio = double(verticalScrollBar()->value() - verticalScrollBar()->minimum()) / double(vRange);
        const QRect vpGeom = viewport()->geometry();
        int y = vpGeom.y() + int((track - vThumbLen) * posRatio);
        // 放在 viewport 右侧预留带内
        int x = vpGeom.right() + 5;
        m_vThumb->setGeometry(x, y, m_vThumb->width(), vThumbLen);
        m_vThumb->show();
    } else if (m_vThumb) {
        m_vThumb->hide();
    }

    // 横向滑块
    if (hRange > 0) {
        const int track = horizontalTrackLength();
        const double posRatio = double(horizontalScrollBar()->value() - horizontalScrollBar()->minimum()) / double(hRange);
        const QRect vpGeom = viewport()->geometry();
        int x = vpGeom.x() + int((track - hThumbLen) * posRatio);
        // 放在 viewport 下侧预留带内
        int y = vpGeom.bottom() + 5;
        m_hThumb->setGeometry(x, y, hThumbLen, m_hThumb->height());
        m_hThumb->show();
    } else if (m_hThumb) {
        m_hThumb->hide();
    }
}

#include "ui/CustomScrollView.moc"


